//设计模式就是一种思想 用来规范编程的代码 更整洁 清晰 维护和拓展等
/*
 * Singleton [ˈsɪŋɡltən]单例模式 && Command [kəˈmænd]命令模式
 *   + 早期的模块化编程
 *     + AMD「require.js」
 *     + CMD/CommonJS 「sea.js & Node」   webpack(Node -> CommonJS)
 *     + ES6 Module
 *     + ...
 *   + 业务逻辑处理
 */
// 单例设计模式：基于单独的实例，来管理某一个模块中的内容，实现模块之间的独立划分「但是也可以实现模块之间方法的相互调用」
// 应用场景：比如一个网站的登录，点击登录后弹出一个登录弹框，即使再次点击，也不会再出现一个相同的弹框

// 程序员A开发的-模块A
var AModule = (function () {
    var data = [];

    function bindHTML() {
        // ...
    }

    function change() {
        // ...
    }

    return {
        change: change
    };
})();

// 程序员B开发的-模块B
var BModule = (function () {
    var data = [];

    function bindHTML() {
        // ...
    }

    AModule.change();

    return {
        bindHTML: bindHTML
    };
})();

//业务来讲：按照一定的顺序一次执行对应的方法，从而实现整个板块功能的开发
/* let SerachModule = (function () {
    let body = document.body;
    function queryData() {}
    function bindHTML() {}
    function handle() {}
    return {
        //init 相当于大脑，可以控制谁先执行 谁后执行「命令模式」
        init:function () {
            queryData();
            bindHTML();
            handle();
        }
    }
})();
SerachModule.init();
 */


/* 
 * Constructor [kənˈstrʌktər]构造器模式
 *    + 类&实例
 *    + 私有&公有属性方法
 *    + 插件组件封装
 */
// AModule:类「构造函数」
 class AModule {
     //构造函数体
    constructor() {
        // this->每个类的实例
        this.arr = [];
    }
    // 原型上 公共的属性和方法
    change(val) {
        this.arr.push(val);
        console.log(this.arr);
    }
}
//new 方法会产生闭包
let A1 = new AModule;
let A2 = new AModule;
console.log(A1, A2);
console.log(A1 === A2); //->false
console.log(A1.arr === A2.arr); //->false
console.log(A1.change === A2.change); //->true change方法是引用关系
A1.change(10);
A2.change(20); 

//new 方法会产生闭包
//每一个实例都是单独的一个空间 很多自己私有属性和方法 还有公共的属性方法
//功能插件需要在页面中使用多次 创建多个不同的实例
//插件组件的封装，类库封装 框架封装....
//有效区分共有和私有



